using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using GeYiHome.Domain.Entities;
using GeYiHome.Domain.Specification.SpecAbstract;
using GeYiHome.PublicLibrary;

namespace GeYiHome.Db.IDbBase
{
    public interface IRepository<TEntity> where TEntity : BaseEntity
    {
        IUnitOfWork UnitOfWork { get; }

        /// <summary>
        /// 获取单个实体对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TKey">The type of the t key.</typeparam>
        /// <param name="id">The identifier.</param>
        /// <returns>TEntity.</returns>
        TEntity Get<TKey>(TKey id);

        /// <summary>
        /// 获取所有对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <returns>IQueryable&lt;TEntity&gt;.</returns>
        IQueryable<TEntity> GetAll();

        /// <summary>
        /// 获取所有符合条件的对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="specification">The specification.</param>
        /// <returns>IQueryable&lt;TEntity&gt;.</returns>
        IQueryable<TEntity> GetAllMatching(ISpecification<TEntity> specification);

        /// <summary>
        /// 分页获取对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TK">The type of the tk.</typeparam>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="specification">The specification.</param>
        /// <param name="orderByExpression">The order by expression.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns>DataPageList&lt;TEntity&gt;.</returns>
        DataPageList<TEntity> GetPageList<TK>(int pageIndex,
            int pageSize, ISpecification<TEntity> specification, Expression<Func<TEntity, TK>> orderByExpression,
            SortEnum sortOrder);

        /// <summary>
        /// 分页获取对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TK">The type of the tk.</typeparam>
        /// <param name="entities">The entities.</param>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="specification">The specification.</param>
        /// <param name="orderByExpression">The order by expression.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns>DataPageList&lt;TEntity&gt;.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">null</exception>
        DataPageList<TEntity> GetPageList<TK>(IQueryable<TEntity> entities, int pageIndex,
            int pageSize, ISpecification<TEntity> specification, Expression<Func<TEntity, TK>> orderByExpression,
            SortEnum sortOrder);

        /// <summary>
        /// 修改对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Modify(TEntity entity);

        /// <summary>
        /// 修改对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entities">The entities.</param>
        void Modify(IEnumerable<TEntity> entities);

        /// <summary>
        /// 按条件修改部分字段
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="specification">The specification.</param>
        /// <param name="value">The value.</param>
        void Modify(ISpecification<TEntity> specification,
            Expression<Func<TEntity, TEntity>> value);

        /// <summary>
        /// 删除对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Remove(TEntity entity);

        /// <summary>
        /// 按条件删除
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="specification">The specification.</param>
        void Remove(ISpecification<TEntity> specification);

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entities">The entities.</param>
        void Remove(IEnumerable<TEntity> entities);

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TKey">The type of the t key.</typeparam>
        /// <param name="id">The identifier.</param>
        void Remove<TKey>(TKey id);
        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entities">The entities.</param>
        void Add(IEnumerable<TEntity> entities);

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Add(TEntity entity);

    }
}
